home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d17 / pr.arc / PR.C < prev    next >
C/C++ Source or Header  |  1987-02-25  |  8KB  |  382 lines

  1. /*
  2.  * a print utility, more UNIX compatible than others
  3.  *
  4.  * pr [ option ] ... [ file ] ...
  5.  *
  6.  */
  7.  
  8. #include <stdio.h>
  9.  
  10. /* Useful Defines */
  11.  
  12. #define FF '\014'
  13. #define MAXFILES 15
  14.  
  15. /* forward function references */
  16.  
  17. char *malloc();
  18. char *tod();
  19.  
  20. /* global definitions */
  21.  
  22. int lines = 66;
  23. int width = 80;
  24. int tab = 8;
  25. int columns = 1;
  26. int isheader = FALSE;
  27. char header[72];
  28. int printheader = TRUE;
  29. int useff = FALSE;
  30. int startpage = 0;
  31. int multiple = FALSE;
  32. char separator = ' ';        /* character to use instead of white space */
  33. char opts[] = "123456789p:h:w:fl:ts:mT:";
  34. int page;
  35. char crlf[] = "\r\n";
  36. char **pgarray;
  37. int usestdin = TRUE;        /* set false when a file argument appears */
  38. int endpage;
  39. int files = 0;            /* index into fp list */
  40. FILE *fp[MAXFILES];        /* array of files for multiple printing */
  41.  
  42. /* declarations */
  43.  
  44. extern int optopt;
  45. extern char *optarg;
  46. extern int optind;
  47. extern char timestr[];
  48.  
  49. /* ------------------------------------------------------------------------ */
  50.  
  51. /* main -- process arguments and cycle through list of files */
  52.  
  53. main(argc,argv)
  54. int argc;
  55. char *argv[];
  56. {
  57.     int switchar;
  58.  
  59.     switchar = swchar();
  60.     while (optind < argc) {
  61.         if (argv[optind][0] != switchar) {
  62.             if (!isheader) strcpy(header,argv[optind]);
  63.             usestdin = FALSE;
  64.             fp[files] = fopen(argv[optind],"r");
  65.             if (fp[files] == NULL) {
  66.                 fprintf(stderr,"pr: can't open %s\r\n",argv[optind]);
  67.             }
  68.             else {
  69.                 if (!multiple) {
  70.                     pr(fp);
  71.                 }
  72.                 else ++files;
  73.             }
  74.             ++optind;
  75.         }
  76.         else if (getopt(argc,argv,opts) == '?') {
  77.             continue;
  78.         }
  79.         else if (optopt == '1') columns = 1;
  80.         else if (optopt == '2') columns = 2;
  81.         else if (optopt == '3') columns = 3;
  82.         else if (optopt == '4') columns = 4;
  83.         else if (optopt == '5') columns = 5;
  84.         else if (optopt == '6') columns = 6;
  85.         else if (optopt == '7') columns = 7;
  86.         else if (optopt == '8') columns = 8;
  87.         else if (optopt == '9') columns = 9;
  88.         else if (optopt == 'p') {
  89.             startpage = atoi(optarg);
  90.         }
  91.         else if (optopt == 'h') {
  92.             isheader = TRUE;
  93.             strcpy(header,optarg);
  94.         }
  95.         else if (optopt == 'w') {
  96.             width = atoi(optarg);
  97.             if (width == 0) width = 72;
  98.         }
  99.         else if (optopt == 'l') {
  100.             lines = atoi(optarg);
  101.             if (lines == 0) lines = 66;
  102.         }
  103.         else if (optopt == 't') {
  104.             printheader = FALSE;
  105.             useff = FALSE;        /* automatically */
  106.         }
  107.         else if (optopt == 'T') {
  108.             tab = atoi(optarg);
  109.             if (tab == 0) tab = 8;
  110.         }
  111.         else if (optopt == 'f') {
  112.             useff = TRUE;
  113.         }
  114.         else if (optopt == 's') {
  115.             separator = optarg[0];
  116.         }
  117.         else if (optopt == 'm') {
  118.             multiple = TRUE;
  119.         }
  120.     } /* end argument processing */
  121.     if (usestdin) {
  122.         fp[files] = stdin;
  123.         pr(fp);
  124.     }
  125.     else if (multiple) {
  126.         if (!isheader) header[0] = 0;
  127.         pr(fp);
  128.     }
  129. }
  130.  
  131. /* ------------------------------------------------------------------------ */
  132.  
  133. pr(fp)
  134. FILE *fp[];
  135. {
  136.     page = 1;
  137.     if (printheader) {
  138.         if (useff) endpage = lines - 7;
  139.         else endpage = lines - 5;
  140.     }
  141.     else {
  142.         useff = FALSE;
  143.         endpage = lines;
  144.     }
  145.  
  146.     while (prpage(fp) != EOF) {
  147.         ++page;
  148.     }
  149. }
  150.  
  151. /* ------------------------------------------------------------------------ */
  152.  
  153. allocpage()
  154. {
  155.     int i;
  156.  
  157.     if (pgarray != NULL) return;
  158.     if ((pgarray = malloc(lines * sizeof(char *))) == NULL)
  159.         perror("out of memory");
  160.     setmem(pgarray,(lines * sizeof(char *)),0);
  161.  
  162.     for (i=0;i<lines;++i) {
  163.         if ((pgarray[i]=malloc(width+2)) == NULL)
  164.             perror("out of memory");
  165.         setmem(pgarray[i],width+2,0);
  166.     }
  167. }
  168.  
  169. /* ------------------------------------------------------------------------ */
  170.  
  171. initpage()
  172. {
  173.     int i;
  174.  
  175.     for (i=0;i<lines;++i) {
  176.         if (pgarray[i] != NULL) {
  177.             setmem(pgarray[i],width+2,0);
  178.         }
  179.     }
  180. }
  181.  
  182. /* ------------------------------------------------------------------------ */
  183.  
  184. cleanup()
  185. {
  186.     int i;
  187.  
  188.     for (i=0;i<lines;++i) {
  189.         if (pgarray[i] != 0) free(pgarray[i]);
  190.     }
  191.     free(pgarray);
  192.     pgarray = NULL;
  193. }
  194.  
  195. /* ------------------------------------------------------------------------ */
  196.  
  197. prpage(fp)
  198. FILE *fp[];
  199. {
  200.     int i;
  201.     char *p;
  202.     int iseof;
  203.  
  204.     iseof = buildpage(fp);
  205.     if (page < startpage) return 0;
  206.  
  207.     for (i=0;i<endpage;++i) {
  208.         p = pgarray[i];
  209.         while (*p) putchar(*p++);
  210.         putchar('\r');
  211.         putchar('\n');
  212.     }
  213.     if (useff) putchar('\f');    
  214.     else if (printheader) {
  215.         for (i=0;i<5;++i) {
  216.             putchar('\r');
  217.             putchar('\n');
  218.         }
  219.     }
  220.     return iseof;
  221. }
  222.  
  223. /* ------------------------------------------------------------------------ */
  224.  
  225. buildpage(fp)
  226. FILE *fp[];
  227. {
  228.     int i;
  229.     int vpos;
  230.     int colwid;
  231.     int start;
  232.     int insidecolumn;
  233.     int retval;
  234.     int startline;
  235.  
  236.     if (pgarray == NULL) allocpage();
  237.     else initpage();
  238.  
  239.     vpos = 0;
  240.     if (printheader && !useff) {
  241.         vpos += 2;
  242.     }
  243.     if (printheader) {
  244.         sprintf(pgarray[vpos++],"%s  %s Page %d",tod(),header,page);
  245.         vpos += 2;
  246.     }
  247.  
  248. /* Variables */
  249.  
  250.     if (columns > 1) colwid = (width/columns) -1;
  251.     else if (multiple) colwid = (width/files) -1;
  252.     start = 0;
  253.  
  254. /* Single column case */
  255.  
  256.     if (!multiple && columns == 1) {
  257.         for (;vpos<endpage;++vpos) {
  258.             retval = buildline(pgarray[vpos],width,fp[files]);
  259.             if (retval == EOF) {
  260.                 fclose(fp[files]);
  261.                 return EOF;
  262.             }
  263.             else if (retval == FF) return 0;
  264.         }
  265.     }
  266.  
  267. /* Multiple column case */
  268.  
  269.     if (!multiple && columns > 1) {
  270.         startline = vpos;
  271.         for (i=0;i<columns;++i) {
  272.             insidecolumn = (i < columns-1);    /* true or false */
  273.             for (;vpos<endpage;++vpos) {
  274.                 if (insidecolumn) 
  275.                     setmem(pgarray[vpos]+start,colwid,' ');
  276.                 else setmem(pgarray[vpos]+start,colwid,0);
  277.                 if (buildline(pgarray[vpos]+start,colwid,fp[files])
  278.                     == EOF) {
  279.                     fclose(fp[files]);
  280.                     return EOF;
  281.                 }
  282.                 if (insidecolumn)
  283.                     charcat(pgarray[vpos],separator);
  284.             } /* end for each line */
  285.             start += (colwid+1);
  286.             vpos = startline;
  287.         } /* end for each column */
  288.     } /* end column mode */
  289.  
  290. /* Multiple file case */
  291.  
  292.     if (multiple) {
  293.         startline = vpos;
  294.         for (i=0;i<files;++i) {
  295.             insidecolumn = (i < files-1);    /* true or false */
  296.             for (;vpos<endpage;++vpos) {
  297.                 if (insidecolumn) 
  298.                     setmem(pgarray[vpos]+start,colwid,' ');
  299.                 else setmem(pgarray[vpos]+start,colwid,0);
  300.                 if (
  301.                    fp[i] != NULL && 
  302.                    buildline(pgarray[vpos]+start,colwid,fp[i])
  303.                     == EOF
  304.                 ) {
  305.                     fclose(fp[i]);
  306.                     fp[i] = NULL;
  307.                 }
  308.                 if (insidecolumn)
  309.                     charcat(pgarray[vpos],separator);
  310.             } /* end for each line */
  311.             start += (colwid+1);
  312.             vpos = startline;
  313.         } /* end for each column */
  314.         for (i=0;i<files;++i) if (fp[i] != NULL) return 0;
  315.         return EOF;
  316.     } /* end multiple */
  317.  
  318.     return 0;
  319. }
  320.  
  321. /* ------------------------------------------------------------------------ */
  322.  
  323. buildline(s,w,fp)
  324. char *s;
  325. int w;
  326. FILE *fp;
  327. {
  328.     int hpos;
  329.     int c;
  330.  
  331.     hpos = 0;
  332.     while ((c = getc(fp)) != EOF) {
  333.         switch (c) {
  334.         case '\n':
  335.             return 0;
  336.             break;
  337.         case '\r':
  338.             break;
  339.         case '\f':
  340.             if (!multiple) return FF;
  341.             break;
  342.         case '\t':
  343.             if (hpos < w) *s++ = ' ';
  344.             ++hpos;
  345.             while ((hpos % tab) && (hpos < w)) {
  346.                 *s++ = ' ';
  347.                 ++hpos;
  348.             }
  349.             break;
  350.         default:
  351.             if (isprint(c) && hpos < w) *s++ = c;
  352.             ++hpos;
  353.             break;
  354.         }
  355.     }
  356.     if (c == EOF) return EOF;
  357.     return 0;
  358. }
  359.  
  360. /* ------------------------------------------------------------------------ */
  361.  
  362. perror(string)
  363. char *string;
  364. {
  365.     cleanup();
  366.     fprintf(stderr,"pr: %s\r\n",string);
  367.     exit(1);
  368. }
  369.  
  370. /* ------------------------------------------------------------------------ */
  371.  
  372. charcat(s,c)
  373. char *s;
  374. int c;
  375. {
  376.     char *p;
  377.     p = s + strlen(s);
  378.     *p++ = c;
  379.     *p = 0;
  380.     return;
  381. }
  382.